package com.pickgliss.ui.text
{
	import com.pickgliss.geom.IntPoint;
	import com.pickgliss.ui.ComponentFactory;
	import com.pickgliss.ui.controls.DisplayObjectViewport;
	import com.pickgliss.ui.controls.ScrollPanel;
	import com.pickgliss.utils.DisplayUtils;
	import com.pickgliss.utils.ObjectUtils;
	import com.pickgliss.utils.StringUtils;
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextFieldType;
	import flash.ui.Keyboard;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;

	public class TextArea extends ScrollPanel
	{
		public static const P_textField:String = "textField";

		public function TextArea()
		{
			super();
			_viewSource.addEventListener(MouseEvent.CLICK,__onTextAreaClick);
			_viewSource.addEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
			_viewSource.addEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
		}
		
		protected var _currentTextHeight:int = 0;
		
		protected var _enable:Boolean = true;
		protected var _textField:FilterFrameText;
		protected var _textStyle:String;
		protected var _limitLines:int = int.MAX_VALUE;
		
		override public function dispose():void
		{
			Mouse.cursor = MouseCursor.AUTO;
			_viewSource.removeEventListener(MouseEvent.CLICK,__onTextAreaClick);
			_viewSource.removeEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
			_viewSource.removeEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
			_textField.removeEventListener(KeyboardEvent.KEY_DOWN,__onTextKeyDown);
			_textField.removeEventListener(Event.CHANGE,__onTextChanged);
			ObjectUtils.disposeObject(_textField);
			_textField = null;
			super.dispose();
		}
		
		public function get editable():Boolean
		{
			return _textField.type == TextFieldType.INPUT
		}
		
		public function set editable(value:Boolean):void
		{
			if(value)
			{
				_textField.type = TextFieldType.INPUT;
				_viewSource.addEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
				_viewSource.addEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
			}else
			{
				_textField.type = TextFieldType.DYNAMIC;
				_viewSource.removeEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
				_viewSource.removeEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
			}
		}
		public function get enable():Boolean
		{
			return _enable;
		}
		
		public function set enable(value:Boolean):void
		{
			_textField.mouseEnabled = _enable;
			if(_enable)
			{
				_viewSource.addEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
				_viewSource.addEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
			}else
			{
				_viewSource.removeEventListener(MouseEvent.MOUSE_OVER,__onTextAreaOver);
				_viewSource.removeEventListener(MouseEvent.MOUSE_OUT,__onTextAreaOut);
			}
		}
		
		public function get maxChars():int
		{
			return _textField.maxChars;
		}
		
		public function set maxChars(value:int):void
		{
			_textField.maxChars=value;
		}
		
		
		public function set limitChars(value:int):void
		{
			_limitLines = value;
		}
		
		public function get text():String
		{
			return _textField.text;
		}
		
		public function set text(value:String):void
		{
			_textField.text = value;
			DisplayObjectViewport(_viewSource).invalidateView();
		}

		public function get textField():FilterFrameText
		{
			return _textField;
		}
		
		public function set textField(tf:FilterFrameText):void
		{
			if(_textField == tf)return;
			if(_textField)
			{
				_textField.removeEventListener(Event.CHANGE,__onTextChanged);
				_textField.removeEventListener(KeyboardEvent.KEY_DOWN,__onTextKeyDown);
				ObjectUtils.disposeObject(_textField);
			}
			_textField = tf;
			_textField.multiline = true;
			_textField.addEventListener(KeyboardEvent.KEY_DOWN,__onTextKeyDown);
			_textField.addEventListener(Event.CHANGE,__onTextChanged);
			onPropertiesChanged(P_textField);
		}
		
		
		public function set textStyle(stylename:String):void
		{
			if(_textStyle == stylename)return;
			_textStyle = stylename;
			textField = ComponentFactory.Instance.creat(_textStyle);
		}
		
		public function get textStyle():String
		{
			return _textStyle;
		}
		
		override protected function layoutComponent():void
		{
			super.layoutComponent();
			var texFieldRect:Rectangle = _viewportInnerRect.getInnerRect(_width,_height);
			_textField.x = texFieldRect.x;
			_textField.y = texFieldRect.y;
			_textField.width = _viewSource.width;
		}
		
		override protected function onProppertiesUpdate():void
		{
			super.onProppertiesUpdate();
			if(_changedPropeties[P_textField])
			{
				DisplayObjectViewport(_viewSource).setView(_textField);
			}
		}
		
		private function __onTextAreaClick(event:MouseEvent):void
		{
			_textField.setFocus();
		}
		
		private function __onTextAreaOut(event:MouseEvent):void
		{
			Mouse.cursor = MouseCursor.AUTO;
		}

		private function __onTextAreaOver(event:MouseEvent):void
		{
			Mouse.cursor = MouseCursor.IBEAM;
		}

		private function __onTextChanged(event:Event):void
		{
			if(StringUtils.checkStringLength(_textField.text) >= _limitLines)
				_textField.text = StringUtils.substr(_textField.text, _limitLines);
			upScrollArea();
		}
		
		public var textString:String = "";
		private function __onTextKeyDown(event:KeyboardEvent):void
		{	
			if(event.keyCode == Keyboard.ENTER)
			{
				event.stopPropagation();
				this.dispatchEvent(event);
			}else if(event.keyCode == Keyboard.UP)
			{
				upScrollArea();
			}else if(event.keyCode == Keyboard.DOWN)
			{
				upScrollArea();
			}else if(event.keyCode == Keyboard.DELETE)
			{
				upScrollArea();
			}
		}
	
		
		private function upScrollArea():void
		{
			DisplayObjectViewport(_viewSource).invalidateView();
			if(_textField.caretIndex <= 0)
			{
				viewPort.viewPosition = new IntPoint(0,0);
			}else
			{
				var lineHeight:Number = DisplayUtils.getTextFieldLineHeight(_textField);
				var currentPos:IntPoint = viewPort.viewPosition;
				var careX:Number = DisplayUtils.getTextFieldCareLinePosX(_textField);
				var careY:Number = DisplayUtils.getTextFieldCareLinePosY(_textField);
				var offsetX:Number = careX - currentPos.x;
				var offsetY:Number = careY+lineHeight - currentPos.y;
				DisplayObjectViewport(_viewSource).invalidateView();
				var resultX:Number = currentPos.x;
				var resultY:Number = currentPos.y;
				if(offsetX < 0)
				{
					resultX = careX;
				}else if(offsetX > viewPort.getExtentSize().width)
				{
					resultX = careX+viewPort.getExtentSize().width;
				}
				if(offsetY < lineHeight)
				{
					resultY = careY-offsetY;
				}else if(offsetY > viewPort.getExtentSize().height)
				{
					resultY = careY+viewPort.getExtentSize().height;
				}
				if(resultX > 0 || resultY > 0)
				{
					viewPort.viewPosition = new IntPoint(resultX,resultY);
				}
			}
		}
	}
}